package com.parleys.android.client.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.json.JSONArray;
import org.json.JSONException;

import android.content.ContentResolver;

import com.parleys.android.client.io.JSONHandler.HandlerException;

public class RemoteExecutor {

	private final HttpClient mHttpClient;
	private final ContentResolver mResolver;

	public RemoteExecutor(HttpClient httpClient, ContentResolver resolver) {
		this.mHttpClient = httpClient;
		this.mResolver = resolver;
	}

	public void executeGet(String url, JSONHandler handler) throws HandlerException {
		final HttpUriRequest request = new HttpGet(url);
		execute(request, handler);
	}

	public void execute(HttpUriRequest request, JSONHandler handler) throws HandlerException {
		try {
			final HttpResponse resp = mHttpClient.execute(request);
			final int status = resp.getStatusLine().getStatusCode();
			if (status != HttpStatus.SC_OK) {
				throw new HandlerException("Unexpected server response "
						+ resp.getStatusLine() + " for "
						+ request.getRequestLine());
			}

			final InputStream input = resp.getEntity().getContent();
			try {
            	final BufferedReader reader = new BufferedReader(new InputStreamReader(input));
            	final StringBuilder sb = new StringBuilder();
            	String line;
            	while ((line = reader.readLine()) != null) {
            		sb.append(line);
            	}
            	final String jsonText = sb.toString();
            	final JSONArray json = new JSONArray(jsonText);
                handler.parseAndApply(json, mResolver);
			} catch (JSONException e) {
                throw new HandlerException("Malformed response for " + request.getRequestLine(), e);
			} finally {
				if (input != null)
					input.close();
			}
		} catch (HandlerException e) {
			throw e;
		} catch (IOException e) {
			throw new HandlerException("Problem reading remote response for " + request.getRequestLine(), e);
		}
	}

}
